using System;
using System.Collections.Generic;
using System.Text;
using PandoraCommon;
using System.IO;
using System.Windows.Forms;

namespace TrackVision
{
    /// <summary>
    /// This plug-in exports the GPS data to a format TrackVision (www.TrackVision.net) recognizes.
    /// </summary>
    public class LogWriter : ILogWriter
    {

        #region ILogWriter Members

        /// <summary>
        /// Name of the log writer plug-in.
        /// </summary>
        /// <value></value>
        public string Name
        {
            get { return "TrackVision Log Exporter"; }
        }

        /// <summary>
        /// Description for the log writer plug-in.
        /// </summary>
        /// <value></value>
        public string Description
        {
            get { return "This plug-in exports the GPS data to a format TrackVision (www.TrackVision.net) recognizes. " + 
                        "Make sure you select the Race Technology Analysis version 4KPH from the loggers " + 
                        "menu in TrackVision when importing."; }
        }

        /// <summary>
        /// Author of this log writer plug-in.
        /// </summary>
        /// <value></value>
        public string Author
        {
            get { return "Mario Sobral 2007"; }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="gpsPositions"></param>
        public void WriteLog(List<GpsPosition> gpsPositions)
        {
            frmSettings writerSettingsForm = new frmSettings();
            writerSettingsForm.ShowDialog();

            SaveFileDialog saveCsvDialog = new SaveFileDialog();
            saveCsvDialog.DefaultExt = "csv";
            saveCsvDialog.FileName = "export.csv";
            saveCsvDialog.Filter = "TrackVision recognizable files (*.csv)|*.csv";
            saveCsvDialog.InitialDirectory = Application.StartupPath;
            saveCsvDialog.OverwritePrompt = true;
            saveCsvDialog.Title = this.Name;
            if (saveCsvDialog.ShowDialog() == DialogResult.OK)
            {
                Cursor.Current = Cursors.WaitCursor;
                try
                {
                    // Prepare coordinates data
                    calculateReferenceCoordinates(gpsPositions);

                    // Write data to file
                    TextWriter csvWriter = new StreamWriter(saveCsvDialog.FileName);
                    double timeElapsed = 0;
                    double distanceTraveled = 0;
                    try
                    {
                        csvWriter.WriteLine("Data Output From Pandora Software Plug-in for TrackVision " + DateTime.Now.ToShortDateString() + ",,,,,,,,,,,,,,,,,,,,");
                        csvWriter.WriteLine("TIME,X,Y,SPEED_KPH,SPEED_MPH,LONGITUDINAL_ACCELERATION,LATERAL_ACCELERATION,DISTANCE_KM,DISTANCE_MILES,DISTANCE_FEET,IS_BRAKING,LATITUDE,LONGITUDE,ALTITUDE_METERS,ALTITUDE_FEET,HEADING");
                        for (int i = 0; i < gpsPositions.Count; i++)
                        {
                            if (i == 0)
                            {
                                csvWriter.WriteLine(new TrackDataItem(gpsPositions[i], latitudeCenter, longitudeCenter, timeElapsed, distanceTraveled).ToTrackVision());
                            }
                            else
                            {
                                double timeGap = gpsPositions[i].TimeSincePreviousPosition;//.TimeSince(gpsPositions[i - 1]);

                                if(timeGap > 0)
                                {
                                    timeElapsed += Math.Round(timeGap / 1000, 1);
                                    distanceTraveled += gpsPositions[i].DistanceTo(gpsPositions[i - 1]);
                                    TrackDataItem newItem = new TrackDataItem(gpsPositions[i], latitudeCenter, longitudeCenter, timeElapsed, distanceTraveled);
                                    string newLine = newItem.ToTrackVision();
                                    csvWriter.WriteLine(newLine);
                                }
                            }
                        }
                    }
                    catch
                    {
                        throw;
                    }
                    finally
                    {
                        csvWriter.Close();
                    }
                    MessageBox.Show("CSV data writen to file: " + saveCsvDialog.FileName, this.Name);
                }
                catch (Exception ex)
                {
                    Cursor.Current = Cursors.Default;
                    MessageBox.Show("Error writing CSV data to file: " + ex.Message, this.Name);
                }
                finally
                {
                    Cursor.Current = Cursors.Default;
                }
            }
        }

        private double maxLatitude = double.MinValue;
        private double minLatitude = double.MaxValue;
        private double maxLongitude = double.MinValue;
        private double minLongitude = double.MaxValue;
        private double latitudeCenter;
        private double longitudeCenter;

        private void calculateReferenceCoordinates(List<GpsPosition> gpsPositions)
        {
            foreach (GpsPosition currentPosition in gpsPositions)
            {
                if (currentPosition.Latitude >= maxLatitude)
                    maxLatitude = currentPosition.Latitude;
                if (currentPosition.Longitude >= maxLongitude)
                    maxLongitude = currentPosition.Longitude;
                if (currentPosition.Latitude < minLatitude)
                    minLatitude = currentPosition.Latitude;
                if (currentPosition.Longitude < minLongitude)
                    minLongitude = currentPosition.Longitude;
            }

            latitudeCenter = maxLatitude - Math.Abs(maxLatitude - minLatitude) / 2;
            longitudeCenter = maxLongitude - Math.Abs(maxLongitude - minLongitude) / 2;

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="gpsPositions"></param>
        public void WriteLogOld(List<GpsPosition> gpsPositions)
        {

            //frmSettings writerSettingsForm = new frmSettings();
            //writerSettingsForm.ShowDialog();

            SaveFileDialog saveCsvDialog = new SaveFileDialog();
            saveCsvDialog.DefaultExt = "csv";
            saveCsvDialog.FileName = "export.csv";
            saveCsvDialog.Filter = "TrackVision recognizable files (*.csv)|*.csv";
            saveCsvDialog.InitialDirectory = Application.StartupPath;
            saveCsvDialog.OverwritePrompt = true;
            saveCsvDialog.Title = this.Name;
            if (saveCsvDialog.ShowDialog() == DialogResult.OK)
            {
                Cursor.Current = Cursors.WaitCursor;
                try
                {
                    // Prepare coordinates data
                    calculateReferenceCoordinates(gpsPositions);

                    // Write data to file
                    TextWriter csvWriter = new StreamWriter(saveCsvDialog.FileName);
                    double timeElapsed = 0;
                    double distanceTraveled = 0;
                    try
                    {
                        csvWriter.WriteLine("Data Output From Pandora Software Plug-in for TrackVision " + DateTime.Now.ToShortDateString() + ",,,,,,,,,,,,,,,,,,,,");
                        csvWriter.WriteLine("Time [s],Accel Longitudinal [g],Accel/Brake Flag [-],Accel Lateral [g],Accel Total [g],Engine Speed [rpm],GPS Speed [mph],GPS Speed [kph],Wheel Speed [mph],Wheel Speed [kph],Distance [km],Distance [miles],Distance [m],Distance [ft],Power [hp],Position X [m],Position Y [m],Time Slip [s],Rate of Time Slip [%],Track Side Beacon [-],Sat Count [-]");
                        for (int i = 0; i < gpsPositions.Count; i++)
                        {
                            if (i == 0)
                            {
                                csvWriter.WriteLine(new TrackDataItem(gpsPositions[i], latitudeCenter, longitudeCenter, timeElapsed, distanceTraveled).ToTrackVision());
                            }
                            else
                            {
                                double timeGap = gpsPositions[i].TimeSincePreviousPosition;//.TimeSince(gpsPositions[i - 1]);

                                if (timeGap > 0)
                                {
                                    timeElapsed += Math.Round(timeGap / 1000, 1);
                                    distanceTraveled += gpsPositions[i].DistanceTo(gpsPositions[i - 1]);
                                    TrackDataItem newItem = new TrackDataItem(gpsPositions[i], latitudeCenter, longitudeCenter, timeElapsed, distanceTraveled);
                                    string newLine = newItem.ToTrackVision();
                                    csvWriter.WriteLine(newLine);
                                }
                            }
                        }
                    }
                    catch
                    {
                        throw;
                    }
                    finally
                    {
                        csvWriter.Close();
                    }
                    MessageBox.Show("CSV data writen to file: " + saveCsvDialog.FileName, this.Name);
                }
                catch (Exception ex)
                {
                    Cursor.Current = Cursors.Default;
                    MessageBox.Show("Error writing CSV data to file: " + ex.Message, this.Name);
                }
                finally
                {
                    Cursor.Current = Cursors.Default;
                }
            }
        }

        #endregion
    }
}
